package com.macllvm.whale.ui.widget;

import android.widget.LinearLayout;
import android.view.LayoutInflater;
import android.content.Context;
import android.widget.ImageButton;
import android.view.animation.Animation;
import android.view.animation.AnimationUtils;
import android.view.animation.Animation.AnimationListener;
import android.util.AttributeSet;
import android.view.View;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Button;
import android.os.AsyncTask;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.AdapterView;
import android.os.Environment;
import android.util.Log;
import java.util.List;
import java.util.ArrayList;
import java.io.File;
import java.util.Stack;
import java.util.Map;
import java.util.HashMap;
import java.util.Set;
import java.util.Iterator;
import java.util.Date;
import java.text.DateFormat;
import com.macllvm.whale.protocol.ProtocolBase;
import com.macllvm.whale.protocol.ProtocolController;
import com.macllvm.whale.entity.Transfer;
import com.macllvm.whale.model.TransferOutManager;
import com.macllvm.whale.entity.FileItem;
import com.macllvm.whale.entity.Message;
import com.macllvm.whale.adapter.FileAdapter;
import com.macllvm.whale.adapter.FileAdapter.SelectHandler;
import com.macllvm.whale.R;

public class FileExplorerPanel extends LinearLayout {

    private Context context;

    private Button  btnClose;
    private Button  btnHome;
    private Button  btnParent;
    private Button  btnTransfer;
    private TextView path;

    private ListView  resourceListView;
    private List<FileItem> resourceList = new ArrayList<FileItem>();
    private List<FileItem> resourceList2 = new ArrayList<FileItem>();
    private List<FileItem> targetList;

    private FileAdapter   adapter;
    private static String rootDir;
    private String currentDir;
    private LoadFileTask   loadTask;
    private Stack dirStack;
    private ProtocolController controller;
    private TransferOutManager transferOutManager;
    private String ip;

    private Map<Integer, Boolean> selectItemsMap = new HashMap<Integer, Boolean>();

    public FileExplorerPanel(Context context, AttributeSet attrs) {
        super(context, attrs);
        this.context = context;
        init();
    }

    private void init() {

        LayoutInflater inflater=(LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
        inflater.inflate(R.layout.file_explorer, this);
        path =  (TextView)findViewById(R.id.directory);

        btnClose =(Button)findViewById(R.id.tool_btn_close);
        btnHome = (Button)findViewById(R.id.tool_btn_home);
        btnParent = (Button)findViewById(R.id.tool_btn_up);
        btnTransfer = (Button)findViewById(R.id.tool_btn_send);

        btnClose.setOnClickListener(new  View.OnClickListener() {
            public void onClick(View v) {

                hide();
            }
        });


        btnHome.setOnClickListener(new  View.OnClickListener() {
            public void onClick(View v) {
                if(dirStack.size() != 0){
                    dirStack.clear();
                    currentDir = rootDir;
                    startLoad();
                }
            }
        });



        btnParent.setOnClickListener(new  View.OnClickListener() {
            public void onClick(View v) {
                int deep = dirStack.size();
                if(dirStack.size() > 0){
                    if(deep == 1) {// && targetList.get(0).name.equals("..")) { //empty directory
                        currentDir = rootDir;//(String)dirStack.pop();
                    }else{

                        if(targetList.get(0).name.equals("..")){ //empty directory
                            dirStack.pop();
                            currentDir = (String)dirStack.peek();
                        }else{
                            currentDir = (String)dirStack.pop();
                        }

                    }
                    Log.v("TAG2", "currdir ="+ currentDir);
                    startLoad();
                }
            }
        });


        btnTransfer.setOnClickListener(new  View.OnClickListener() {
            public void onClick(View v) {
            if(selectItemsMap.size() > 0) {
                SendFileInfoTask sendTask = new SendFileInfoTask();
                sendTask.execute();
            }

            }
        });

        resourceListView = (ListView) findViewById(R.id.file_list);
        resourceListView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
        resourceListView.setOnItemClickListener(new FileItemClickListener());
        resourceListView.setFastScrollEnabled(true);

        adapter = new FileAdapter(context);
        adapter.setDataSource(resourceList);
        adapter.setSelectHandler(new FileItemOnSelect());
        resourceListView.setAdapter(adapter);

        rootDir = Environment.getExternalStorageDirectory().getAbsolutePath(); //"/mnt/sdcard/";
        Log.v("TAG", "root="+rootDir);
        currentDir = rootDir;
        dirStack = new Stack();

        startLoad();

        controller = ProtocolController.getInstance();
        transferOutManager = controller.getTransferOutManager();


    }

    private class FileItemOnSelect implements SelectHandler  {
        public void onSelect(int index, boolean isChecked){
            if(isChecked) {
                selectItemsMap.put(index, isChecked);
            }else{
                selectItemsMap.remove(index);
            }
        }
    }

    public void setIP(String ip){
        this.ip = ip;
    }

    public void show(){
        if(resourceList.size() == 0) {
            startLoad();
        }

        path.setText(currentDir);
        setVisibility(View.VISIBLE);
        Animation showAnim=AnimationUtils.loadAnimation(context, R.anim.panel_show);
        this.startAnimation(showAnim);
    }

    public void hide(){
        dirStack.clear();

        selectItemsMap.clear();
        resourceList.clear();
        resourceList2.clear();

        currentDir = rootDir;

        Animation hideAnim=AnimationUtils.loadAnimation(context, R.anim.panel_hide);
        hideAnim.setAnimationListener(hideAnimListener);
        this.startAnimation(hideAnim);

    }


    private AnimationListener  showAnimListener = new AnimationListener() {
        @Override
        public void onAnimationStart(Animation animation) {

        }

        @Override
        public void onAnimationEnd(Animation animation) {
            setVisibility(View.GONE);
        }

        @Override
        public void onAnimationRepeat(Animation animation) {

        }
    };

    private AnimationListener  hideAnimListener = new AnimationListener() {
        @Override
        public void onAnimationStart(Animation animation) {

        }

        @Override
        public void onAnimationEnd(Animation animation) {
            setVisibility(View.GONE);
        }

        @Override
        public void onAnimationRepeat(Animation animation) {

        }
    };


    private void startLoad(){
        loadTask = new LoadFileTask();
        loadTask.execute();
    }

    private class FileItemClickListener implements OnItemClickListener {
        public void onItemClick(AdapterView<?> parent, View view, int pos, long id) {

            FileItem item = (FileItem)targetList.get(pos);

            if(item.type == FileItem.TYPE_DIR){
                if( !( "..".equals(item.name)) ){
                    currentDir = currentDir + "/" + item.name;
                    dirStack.push(currentDir);
                }else{
                    dirStack.pop();
                    currentDir = (String)dirStack.peek();

                }
                startLoad();
            }
        }
    }

    protected void getDirectory() {
        File dir = new File(currentDir);
        File[] files = dir.listFiles();

        if(resourceList.size() == 0){
            targetList = resourceList;
        }else{
            targetList = resourceList2;
        }

        if(files.length == 0){
            FileItem item = new FileItem();
            item.type =  FileItem.TYPE_DIR;
            item.name = "..";
            item.size = 0;
            targetList.add(item);
        }

        for (File file: files) {

            FileItem item = new FileItem();

            if (file.isDirectory()) {
                item.type =  FileItem.TYPE_DIR;
            } else {
                item.type =  FileItem.TYPE_FILE;
            }
            item.name = file.getName();
            item.size = file.length();
            item.modifyTime = file.lastModified();
            targetList.add(item);
        }

    }

    private void resetSelectItems(){
        if(selectItemsMap.size() > 0) {
            selectItemsMap.clear();
        }
        adapter.notifyDataSetChanged();
    }

    public class LoadFileTask extends AsyncTask<Void, Object, Void> {

        @Override
        protected void onPreExecute() {

        }

        @Override
        protected Void doInBackground(Void... arg0) {
            getDirectory();
            return null;
        }

        @Override
        protected void onPostExecute(Void result){
            if(resourceList == targetList) {
                adapter.setDataSource(resourceList);
                if(resourceList2.size() > 0){
                    resourceList2.clear();
                }
            }
            else {
                adapter.setDataSource(resourceList2);
                if(resourceList.size() > 0){
                    resourceList.clear();
                }
            }

            resetSelectItems();

            path.setText(currentDir);
        }
    }




    public class SendFileInfoTask extends AsyncTask<Void, Object, Void> {
        StringBuffer buffer = new StringBuffer(256);

        private void sendFileInfo() {
            int number = 0;
            buffer.delete(0, buffer.length());
            buffer.append('\0');
            Set<Integer> set = selectItemsMap.keySet();
            int count = targetList.size();


            String fileList ="";
            for( Integer i : set) {
                int index = i;
                boolean isSelect = selectItemsMap.get(i);
                if(isSelect){

                    FileItem item = (FileItem)targetList.get(i);
                    Transfer t = new  Transfer();
                    t.fileId = transferOutManager.getSendFileId() ;
                    t.packetNumber = 0;
                    t.fileAttr = ProtocolBase.IPMSG_FILE_REGULAR;
                    t.fileSize = item.size;
                    t.filePath = currentDir + "/" + item.name;
                    t.fileCreateTime = item.modifyTime;
                    t.fileNumber = number;
                    t.transferType = Transfer.TYPE_SEND;

                    buffer.append(String.valueOf(t.fileId));
                    buffer.append(":");
                    buffer.append(item.name);
                    buffer.append(":");
                    buffer.append(Long.toHexString(t.fileSize));
                    buffer.append(":");
                    buffer.append(Long.toHexString(t.fileCreateTime));
                    buffer.append(":");
                    buffer.append(String.valueOf(t.fileAttr));
                    buffer.append(":");
                    buffer.append( (char)0x07 );

                    if(number > 0)
                        fileList += "\n";
                    fileList += item.name;

                    controller.getTransferOutManager().add(t);

                }
                number++;
            }
            buffer.append('\0');
            controller.sendFileInfo(ip, buffer.toString());

            Date now = new Date();
            DateFormat df = DateFormat.getDateTimeInstance();
            String datetime = df.format(now);
            Message m = new Message(datetime, fileList, Message.MESSAGE_TIP_OUT);
            controller.getMessageManager().add(ip, m);
        }

        @Override
        protected void onPreExecute() {

        }

        @Override
        protected Void doInBackground(Void... arg0) {
            sendFileInfo();
            return null;
        }

        @Override
        protected void onPostExecute(Void result){
            resetSelectItems();
        }
    }


}
